package cn.iocoder.yudao.module.call.job;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.call.controller.admin.stat.vo.CallStatRespVO;
import cn.iocoder.yudao.module.call.dal.dataobject.stat.StatDO;
import cn.iocoder.yudao.module.call.dal.mysql.stat.StatMapper;
import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;

/**
 * 呼叫中心-数据报表统计定时任务
 */
@Component
@Slf4j
public class CallStatJob implements JobHandler {

    @Resource
    private StatMapper statMapper;

    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private TenantApi tenantApi;

    @Override
    @TenantJob
    public String execute(String param) throws Exception {
//        Float callCostPrice = tenantApi.getCallCostPrice(TenantContextHolder.getTenantId());
        //统计两小时前的
        DateTime begin = DateUtil.beginOfHour(DateUtil.date()).offset(DateField.HOUR, -2);
        int year = begin.year();
        int month = begin.month();
        int day = begin.dayOfMonth();
        int week = begin.weekOfYear();
        int hour = begin.hour(true);
        LocalDateTime[] times = new LocalDateTime[]{
                DateUtil.beginOfHour(begin).toLocalDateTime(),
                DateUtil.beginOfHour(begin).offset(DateField.HOUR, +1).offset(DateField.SECOND,-1).toLocalDateTime()
        };

        StatDO statExist = statMapper.selectOne(new LambdaQueryWrapperX<StatDO>()
                .eq(StatDO::getYear, year)
                .eq(StatDO::getMonth, month)
                .eq(StatDO::getDay, day)
                .eq(StatDO::getHour, hour)
        );
        // 获取最后一条 last one
        StatDO lastStat = statMapper.selectOne(new LambdaQueryWrapperX<StatDO>().orderByDesc(StatDO::getId).last("limit 1"), false);

        //存在当前时间的表示执行过了,防止重复
        if (ObjectUtil.isNotEmpty(statExist)) {
            return "success";
        }
        List<CallStatRespVO> callStatList = statMapper.selectCallStat(times);
        if (ObjectUtil.isEmpty(callStatList)) {
            return "success";
        }
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(callStatList, CallStatRespVO::getOwnerUserId));
        callStatList.forEach(stat -> MapUtils.findAndThen(userMap, stat.getOwnerUserId(), user -> {
            StatDO statDO = BeanUtils.toBean(stat, StatDO.class);
            statDO.setDeptId(user.getDeptId());
            statDO.setRate(NumberUtil.round(NumberUtil.div(stat.getSuccessCount(), stat.getTotalCount()).doubleValue() * 100, 2).doubleValue());
            statDO.setYear(year);
            statDO.setMonth(month);
            statDO.setDay(day);
            statDO.setWeek(week);
            statDO.setHour(hour);
            // 计算当日利润
            statDO.setCurrentProfit(NumberUtil.round(NumberUtil.sub(stat.getCallSalePrice(), stat.getCallCostPrice()), 2).doubleValue());
            Double totalProfit = Objects.isNull(lastStat) ? statDO.getCurrentProfit() : NumberUtil.round(NumberUtil.add(lastStat.getTotalProfit(), statDO.getCurrentProfit()), 2).doubleValue();
            statDO.setTotalProfit(totalProfit);
            statMapper.insert(statDO);
        }));
        return "success";
    }
}
